//
//  CharacterNode.m
//  iFly
//
//  Created by User-10 on 12/7/14.
//  Copyright (c) 2014 TeamDifferent. All rights reserved.
//

#import "CharacterNode.h"
#import "Constants.h"
#import "ShieldButtonNode.h"
#import "GameOverScene.h"
#import "SoundHandler.h"
#import "BossScene.h"

@implementation CharacterNode

+(instancetype) characterWithPosition:(CGPoint) position inScene:(SKScene*) scene {
    CharacterNode* character = [self spriteNodeWithImageNamed:ironManForward];
    
    //setting physical logic for the character
    
    character.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:character.size.width/2*characterPhyisicsBodyScaling center:character.anchorPoint];
    character.physicsBody.affectedByGravity = NO;
    character.physicsBody.categoryBitMask = characterCategory;
    character.physicsBody.dynamic = YES;
    character.physicsBody.contactTestBitMask = obstacleCategory;
    character.physicsBody.collisionBitMask = 0;
    character.name = @"character";
    character.position = position;
    
    //setting properties of the character
    character.lives = characterLives;
    character.isRefreshEnabled = YES;
    character.isShootingWithLeft = YES;
    character.isForward = YES;
    character.isDead = NO;
    
    //setting smoke emitter of the character
    character.smokeEmitter = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"Smoke" ofType:@"sks"]];
    character.smokeEmitter.position = character.position;
    character.smokeEmitter.name = @"Smoke";
    character.smokeEmitter.particleBirthRate = 0;
    [scene addChild:character.smokeEmitter];
    
    
    return character;
}

-(void) moveBackwards {
    if (self.isRefreshEnabled && !self.isDead && self.physicsBody.categoryBitMask == characterCategory) {
        [self setTexture:[SKTexture textureWithImageNamed:ironManBack]];
        self.isForward = NO;
    }
}

-(void) moveForward {
    if (self.isRefreshEnabled && !self.isDead && self.physicsBody.categoryBitMask == characterCategory) {
        [self setTexture:[SKTexture textureWithImageNamed:ironManForward]];
        self.isForward = YES;
    }
}
-(void) flyToTheBossScene {
    if (self.isDead) {
        return;
    }
    //play fly to the boss sound
    [[SoundHandler sharedSoundPlayer]  playSoundWithName:flyBySound andType:@"mp3"];
    
    //removing notifications for background
    [[NSNotificationCenter defaultCenter] removeObserver:[self.parent childNodeWithName:@"pause"]];
    [self setTexture:[SKTexture textureWithImageNamed:ironManForward]];
    CGPoint position= self.position;
    SKAction* rotate= [SKAction rotateByAngle:-M_PI_4/2 duration:0.2];
    SKAction* flyOver=[SKAction moveTo:(CGPointMake(position.x+outOfScreenOffset/2, position.y)) duration:4.0];
    SKAction* presentBossScene = [SKAction runBlock:^{
        
        SKTransition* reveal = [SKTransition fadeWithDuration:1.0];
        BossScene* bossScene=[[BossScene alloc] initWithSize:self.parent.scene.view.bounds.size andScore:self.characterScore];
        bossScene.initialLives = self.lives;
        bossScene.scaleMode = SKSceneScaleModeAspectFill;
        [self.parent.scene.view presentScene:bossScene transition:reveal];
        
    }];self.physicsBody.categoryBitMask=deadCategory;
    self.isDead=YES;
    [self.shield removeFromParent];
    [self.smokeEmitter removeFromParent];
    [self moveForward];
    [self runAction:[SKAction sequence:@[rotate,flyOver,presentBossScene]]];
    
}

-(void) shoot {
    //setting shooting scale to 0.30 for all except back right shooting
    if (self.isDead || self.physicsBody.categoryBitMask == shieldCategory) {
        return;
    }
    
    // [self setScale:0.35];
    self.isShootingWithLeft = !(self.isShootingWithLeft);
    
    
    //shooting left or right and checking if forward or backward
    if (self.isShootingWithLeft) {
        if (self.isForward) {
            [self setTexture:[SKTexture textureWithImageNamed:ironManForwardLeftShoot]];
        }
        else {
            [self setTexture:[SKTexture textureWithImageNamed:ironManBackLeftShoot]];
        }
    }
    else {
        if (self.isForward) {
            [self setTexture:[SKTexture textureWithImageNamed:ironManForwardRightShoot]];
        }
        else {
            [self setTexture:[SKTexture textureWithImageNamed:ironManBackRightShoot]];
            //[self setScale:0.40];
        }
    }
    //locking refreshing for 1.2 seconds after a shot
    self.isRefreshEnabled = NO;
    SKAction *wait = [SKAction waitForDuration:1.2];
    SKAction *reenableJoystick = [SKAction runBlock:^{
        self.isRefreshEnabled = YES;
    }];
    SKAction *sequence = [SKAction sequence:@[wait, reenableJoystick]];
    [self runAction:sequence];
}

-(void) wasHit {
    //adding more smoke after each hit
    self.smokeEmitter.particleBirthRate += smokeEmitterStepIncrease;
    self.lives--;
    [self healthBarUpdate];
    [[SoundHandler sharedSoundPlayer] playSoundWithName:@"explosion_large" andType:@"caf"];
    
    //checking if character is dead
    if (self.lives == 0) {
        
        //removing notifications for background
        [[NSNotificationCenter defaultCenter] removeObserver:[self.parent childNodeWithName:@"pause"]];
        
        SKAction* waitForExplosion=[SKAction waitForDuration:0.5];
        SKAction* playDyingSound=[SKAction runBlock:^{
            [[SoundHandler sharedSoundPlayer] playSoundWithName:@"IronManDying" andType:@"mp3"];
        }];
        
        self.isDead = YES;
        [self setTexture:[SKTexture textureWithImageNamed:ironManParts]];
        self.physicsBody.categoryBitMask = deadCategory;
        
        SKAction* fade = [SKAction fadeAlphaTo:0.0 duration:2];
        SKAction* removeSmoke = [SKAction runBlock:^{
            [self.smokeEmitter removeFromParent];
        }];
        SKAction* wait=[SKAction waitForDuration:0.5];
        SKAction* removeCharacter = [SKAction removeFromParent];
        SKAction* presentGameOverScene = [SKAction runBlock:^{
            NSLog(@"game over");
            
            SKTransition* reveal = [SKTransition doorsOpenVerticalWithDuration:1.0];
            SKScene* gameOverScene=[[GameOverScene alloc] initWithSize:self.parent.scene.size score:self.characterScore gameIsWon:NO];
            [self.parent.scene.view presentScene:gameOverScene transition:reveal];
            
        }];
        SKAction* sequence = [SKAction sequence:@[waitForExplosion,playDyingSound,fade, removeSmoke,wait,presentGameOverScene,removeCharacter]];
        [self runAction:sequence];
        //testing sound singleton class
        [[SoundHandler sharedSoundPlayer] playSoundWithName:@"explosion_large" andType:@"caf"];
    }
    
}

-(void) wasHealed {
    if (self.lives != 0 && self.lives < characterLives) {
        //play heal sound
        [[SoundHandler sharedSoundPlayer] playSoundWithName:@"HealSound" andType:@"mp3"];
        
        self.smokeEmitter.particleBirthRate -= smokeEmitterStepIncrease;
        self.lives++;
        [self healthBarUpdate];
        [[SoundHandler sharedSoundPlayer] playSoundWithName:@"HealSound" andType:@"mp3"];
        
        SKEmitterNode* healEmitter = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"Magic" ofType:@"sks"]];
        healEmitter.position = self.position;
        healEmitter.name = @"Heal";
        [self.parent addChild:healEmitter];
        
        SKAction* fadeEmitter = [SKAction fadeAlphaTo:0.0 duration:1.5];
        SKAction* remove = [SKAction removeFromParent];
        SKAction* sequence = [SKAction sequence:@[fadeEmitter, remove]];
        [healEmitter runAction:sequence];
    }
}

-(void) activateShield {
    if (self.isDead) {
        return;
    }
    self.shield = [SKSpriteNode spriteNodeWithImageNamed:kImageNameForShieldBaseImage];
    
    //setting physical body for the shield
    self.physicsBody.categoryBitMask = shieldCategory;
    [self.shield setScale:self.parent.scene.frame.size.height/800 * shieldScaling];
    
    //shield sound
    [[SoundHandler sharedSoundPlayer] playSoundWithName:@"shield" andType:@"wav"];
    
    NSMutableArray* textures = [[NSMutableArray alloc] init];
    
    for (int idx = 1; idx <= numberOfShieldImages; idx++) {
        NSString* textureName = [NSString stringWithFormat:@"%@0%d",kImageNameForShieldBaseImage,idx];
        SKTexture* texture = [SKTexture textureWithImageNamed:textureName];
        [textures addObject:texture];
    }
    
    
    self.shield.position = CGPointMake(self.position.x, self.position.y-kShieldYPosition);
    
    [self setTexture:[SKTexture textureWithImageNamed:ironManShieldState]];
    [self.parent addChild:self.shield];
    
    SKAction* move = [SKAction animateWithTextures:textures timePerFrame:0.05];
    SKAction* rest = [SKAction setTexture:[textures objectAtIndex:[textures count]-1]];
    
    SKAction* animateShield = [SKAction sequence:@[move,rest]];
    [self.shield runAction:animateShield];
}

// score incrementing
-(void) addScore:(NSInteger) score {
    
    self.characterScore+=score;
    SKLabelNode* scoreLabel= (SKLabelNode*)[self.parent childNodeWithName:@"score"];
    scoreLabel.text=[NSString stringWithFormat:@"Score: %lu",(unsigned long)self.characterScore];
}


//health bar status updating
-(void) healthBarUpdate {
    SKSpriteNode* healthBar=(SKSpriteNode*)[self.parent childNodeWithName:@"healthBar"];
    
    NSString* healthBarTextureName=[NSString stringWithFormat:@"HealthBar%ld",(long)self.lives];
    [healthBar setTexture:[SKTexture textureWithImageNamed:healthBarTextureName]];
}

-(void) initialSetLives:(NSInteger) lives {
    self.smokeEmitter.particleBirthRate += (self.lives-lives) * smokeEmitterStepIncrease;
    self.lives = lives;
    [self healthBarUpdate];
}

-(void)deactivateShield {
    
    
    if (self.isDead) {
        return;
    }
    
    NSMutableArray* reverseTextures = [[NSMutableArray alloc] init];
    
    for (int i = numberOfShieldImages; i > 0; i--) {
        NSString* textureName = [NSString stringWithFormat:@"%@0%d",kImageNameForShieldBaseImage,i];
        SKTexture* texture = [SKTexture textureWithImageNamed:textureName];
        [reverseTextures addObject:texture];
    }
    
    SKAction* moveBackwards = [SKAction animateWithTextures:reverseTextures timePerFrame:0.05];
    SKAction* remove = [SKAction removeFromParent];
    
    SKAction* animateShield = [SKAction sequence:@[moveBackwards,remove]];
    [self.shield runAction:animateShield];
    self.physicsBody.categoryBitMask = characterCategory;
    [self moveForward];
}

-(void)setLives:(NSInteger)lives {
    if (lives < 0) {
        _lives = 0;
    }
    else {
        _lives = lives;
    }
}

@end
